package com.cloudminds.nativeapplication.ble.custome;

import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;
import android.content.Context;
import android.util.Log;

import androidx.annotation.NonNull;

import com.cloudminds.nativeapplication.ble.RcListener;
import com.cloudminds.nativeapplication.ble.RemoteVoiceBleManger;
import com.cloudminds.nativeapplication.utils.BleDeviceUtil;

import java.util.Deque;
import java.util.LinkedList;
import java.util.UUID;

import no.nordicsemi.android.ble.Request;
import no.nordicsemi.android.ble.utils.ParserUtils;

/**
 * @Description TODO
 * Created by sain on 2021/3/8 Monday.
 * Copyright © 2020 AISpeech. All rights reserved.
 * ================================================================================
 */
public class CustomVoiceGattProvider extends RemoteVoiceBleManger {
    private static final String TAG = "CustomVoiceGattProvider";

    // 要监听的primary services
    public final static UUID UUID_SERVICE = UUID.fromString("a8253f01-0c51-4000-b84f-1500068fb5a3");

    public final static UUID UUID_KEY_CHAR = UUID.fromString("a8253f02-0c51-4000-b84f-1500068fb5a3");
    public final static UUID UUID_DATA_CHAR = UUID.fromString("a8253f03-0c51-4000-b84f-1500068fb5a3");

    private BluetoothGattCharacteristic mVoiceKeyCharacteristic;
    private BluetoothGattCharacteristic mVoiceDataCharacteristic;

    private final String FLAG_VOICE_KEY_ADPCM = "cf0200";
    private final String FLAG_VOICE_KEY_UP = "cccc";

    private boolean supported = false;
    private BluetoothDevice mDevice;

    private String bleName = "语音助手";

    private RcListener rcListener;

    public void setRcListener(RcListener rcListener) {
        this.rcListener = rcListener;
    }

    public CustomVoiceGattProvider(@NonNull Context context) {
        super(context);
        mDevice = BleDeviceUtil.getTargetBondedBleDevice(context, bleName);
    }

    @NonNull
    @Override
    protected BleManagerGattCallback getGattCallback() {
        return new CustomGattCallback();
    }

    @Override
    protected BluetoothDevice getTargetDevice() {
        return mDevice;
    }

    /**
     * 自定义的GattCallback， 监听需要监听的Service
     */
    private class CustomGattCallback extends BleManagerGattCallback {
        @Override
        protected boolean isRequiredServiceSupported(BluetoothGatt gatt) {
            final BluetoothGattService service = gatt.getService(UUID_SERVICE);
            if (service != null) {
                Log.d(TAG, "isRequiredServiceSupported:");
                mVoiceKeyCharacteristic = service.getCharacteristic(UUID_KEY_CHAR);
                mVoiceDataCharacteristic = service.getCharacteristic(UUID_DATA_CHAR);
            }
            supported = mVoiceKeyCharacteristic != null && mVoiceDataCharacteristic != null;
            Log.d(TAG, "isRequiredServiceSupported: " + supported);
            return supported;
        }

        @Override
        protected Deque<Request> initGatt(BluetoothGatt gatt) {
            Log.d(TAG, "initGatt: ");
            final LinkedList<Request> requests = new LinkedList<>();
            requests.add(Request.newEnableNotificationsRequest(mVoiceKeyCharacteristic));
            requests.add(Request.newEnableNotificationsRequest(mVoiceDataCharacteristic));
            return requests;
        }

        @Override
        protected void onDeviceDisconnected() {
            mVoiceKeyCharacteristic = null;
            mVoiceDataCharacteristic = null;
        }

        @Override
        protected void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
            super.onCharacteristicRead(gatt, characteristic);
        }

        @Override
        protected void onCharacteristicNotified(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
            super.onCharacteristicNotified(gatt, characteristic);
            if (null != characteristic && supported) {
                if (mVoiceKeyCharacteristic == characteristic) {
                    //key event
                    byte[] value = characteristic.getValue();
                    if (null != value) {
                        onOriginKeyProcess(value);
                    }
                } else if (mVoiceDataCharacteristic == characteristic) {
                    //voice data
                    byte[] buf = characteristic.getValue();
                    if (null != buf && isConnected()) {
                        onOriginVoiceProcess(buf);
                    }
                }
            } else {
                Log.e(TAG, "onCharacteristicNotified: characteristic is null");
                Log.w(TAG, "supported = " + supported);
            }
        }
    }

    private void onOriginKeyProcess(byte[] data) {
        String keyCode = ParserUtils.bytes2String16(data);
        Log.d(TAG, "onOriginKeyProcess: " + keyCode);
        if (FLAG_VOICE_KEY_ADPCM.equals(keyCode)) {
            //按下
            if (rcListener != null) {
                rcListener.onKeyEvent(1);
            }
        } else if (keyCode.startsWith(FLAG_VOICE_KEY_UP)) {
            //抬起
            if (rcListener != null) {
                rcListener.onKeyEvent(0);
            }
        }
    }

    private void onOriginVoiceProcess(byte[] data) {
        Log.d(TAG, "onOriginVoiceProcess: " + data.length);
        //TODO 原始语音数据，一般需要解密解码
        if (rcListener != null) {
            rcListener.onBuffer(data);
        }
    }
}
